#!/usr/bin/env python

# Written By: Alan Viars, and Chris Boyce  - Videntity systems, Inc.

import os
import sys
import re


class omheparser:
    
    def __init__(self, **kwargs):
        self.__dict__ = kwargs
        self.list = {}
        #print self.omhe_str
        self.split_omhe()
       
    
    def split_omhe(self):
        
        #findall the ** and ""
        string_re = \
            r'''
                \*.*?\*          #value syntax ** with spaces *This is my value*
                |
                \".*\"          #value syntax "" with spaces "This is my value"
            '''
            #\s+ #split message at whitespace
        stringPattern = re.compile(string_re, re.VERBOSE)
        
        #find the strings with space delimited by **
        self.string_with_spaces = stringPattern.findall(self.omhe_str)
        #print self.string_with_spaces 
        
        #split at spaces
        space_re = \
            r'''
                \s+         #detect spaces
                
            '''
        spacePattern = re.compile(space_re, re.VERBOSE)
        
        #initialize piped list
        self.piped_list = []
        for string_index, string in enumerate(self.string_with_spaces):
            #print string_index
            #print string
        
            #substitute spaces with pipes !
            string_with_spaces_piped = spacePattern.sub('|', string)
            #print string_index
            #print string_with_spaces_piped
            
            #create the piped list
            self.piped_list.insert(string_index, string_with_spaces_piped)
            
            #remove leading " or *
            string = string[1:]
            string_with_spaces_piped = string_with_spaces_piped[1:]
            #remove trailing " or *
            string = string[:-1]
            string_with_spaces_piped = string_with_spaces_piped[:-1]
            
            string_with_spaces = '%s'%(string)
            
            #print string_with_spaces
            stringPattern_replace = re.compile(string_with_spaces)
            #print string
            #print string_with_spaces_piped
            #print self.omhe_str
            self.omhe_str = stringPattern_replace.sub(string_with_spaces_piped, self.omhe_str)
            #print self.omhe_str
        
        #split message at white space
        self.omhemessages = spacePattern.split(self.omhe_str)

        #print 
        #print "number of omhe messages: %s" %len(self.omhemessages)
        #print
        
        #go through each word(message) in the string
        for message_index, message in enumerate(self.omhemessages):
                #initialize omhe dict
                self.list[message_index] = {}
                #print
                #print "ohme message: %s" %message
                #print "ohme message index: %s" %message_index
                
                ####################################################################
                #help
                ####################################################################
                #make sure self.omhe is not already set for the message index
                if not self.list[message_index]:
                    #parse out help first because it has omhe syntax inside of it
                    self.parse_hp(message, message_index)
                
                ####################################################################
                #healthcard
                ####################################################################
                if not self.list[message_index]:
                    #parse out ghc
                    self.parse_ghc(message, message_index)
                
                if not self.list[message_index]:
                    #parse out shc with emails
                    self.parse_shcemail(message, message_index)
                    
                if not self.list[message_index]:
                    #parse out shc with fax numbers
                    self.parse_shcfax(message, message_index)
                    
                if not self.list[message_index]:
                    #parse out hc with urls
                    self.parse_hcurl(message, message_index)
                
                ####################################################################
                #menstrual cycle
                ####################################################################
                if not self.list[message_index]:
                    #parse out gmc
                    self.parse_gmc(message, message_index)
                if not self.list[message_index]:
                    #parse out smc
                    self.parse_smcemail(message, message_index)
                if not self.list[message_index]:
                    #parse out mc
                    self.parse_mc(message, message_index)
                if not self.list[message_index]:
                    #parse out wt
                    self.parse_wt(message, message_index)
                if not self.list[message_index]:
                    #parse out bp
                    self.parse_bp(message, message_index)
                if not self.list[message_index]:
                    #parse out gbp
                    self.parse_gbp(message, message_index)
                if not self.list[message_index]:
                    #parse out sbp
                    self.parse_sbpemail(message, message_index)
                
                #no supported syntax, through error
                if not self.list[message_index]:
                    omhemessage_dict = {}
                    omhemessage_dict['message'] = message
                    omhemessage_dict['error'] = 'invalid syntax'
                    self.list[message_index] = omhemessage_dict
                    
                    
                #print  "parsed dict: %s" %self.list[message_index]
                
    ####################################################################
    #help
    ####################################################################
    def generate_dict(self, message, message_index, omhe_REGEXP, command):
        
        #compile the regular expression so that it is case insensitive
        omhePattern = re.compile(omhe_REGEXP, re.VERBOSE | re.I)
        
        #find the expressions in the message
        re_message = omhePattern.search(message)
        
        #get the regular expression message dictionary
        re_dict = re_message.groupdict()

        #initialize omhe dictionary
        omhemessage_dict = {}
        
        #find pipes
        pipe_re = \
            r'''
                \|         #detect spaces
                
            '''
        pipePattern = re.compile(pipe_re, re.VERBOSE)
        
        #substitute spaces for pipes
        message = string_with_spaces_piped = pipePattern.sub(' ', message)
        
        #set message to the input message string
        omhemessage_dict['message'] = message
        
        #set the command, value, and tag
        for parser_key, parser_value in re_dict.iteritems():
            #print 'key=%s' %parser_key
            #print 'value=%s' %parser_value

            #check for strings that we pipe delimited
            for string_index, string_piped in enumerate(self.piped_list):

                if string_piped == parser_value:
                    string_with_spaces=self.string_with_spaces[string_index] 
                    #remove leading " or *
                    string_with_spaces = string_with_spaces[1:]
                    #remove trailing " or *
                    string_with_spaces = string_with_spaces[:-1]
                    #put back in the string with spaces
                    parser_value = string_with_spaces
                    
            omhemessage_dict[parser_key] = parser_value
            #print omhemessage_dict
        
        #set the command to avoid aliases 
        omhemessage_dict['command'] = command
        
        import uuid
        uuid = uuid.uuid4()
        omhemessage_dict['uuid'] = str(uuid)
            
        #split extra tags if necessary
        tag_split = omhemessage_dict['tag'].split('#')
        for tag in tag_split:

            if tag[0:2] == 'dt':
                omhemessage_dict['date'] = tag[2:]
            
            if tag[0:2] == 'tz':
                omhemessage_dict['tzoffset'] = tag[3:]
            
                
        omhemessage_dict['tag'] = tag_split
        
        #set the value to '' if it doesn't exist
        if 'value' not in omhemessage_dict:
             omhemessage_dict['value'] = ''
        if 'tag' not in omhemessage_dict:
            omhemessage_dict['tag'] = ''
        if 'date' not in omhemessage_dict:
            omhemessage_dict['date'] = ''
        if 'tzoffset' not in omhemessage_dict:
            omhemessage_dict['tzoffset'] = ''
            
        #add to the list of omhe messages
        self.list[message_index] = omhemessage_dict
                        
    ####################################################################
    #help
    ####################################################################
    #parse out help
    def parse_hp(self, message, message_index):

        omhe_REGEXP = \
            r'''
            (?P<command>help=|help|hp=|hp)              #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)   #value
            \#*                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''
        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'hp')
        except:
            pass
            #print "no sendhc"
            #self.omhe[message_index] = "extraction error"
            
            
            
    
    ####################################################################
    #healthcard
    ####################################################################
    #parse out sendhealthcard with email
    def parse_shcemail(self, message, message_index):

        omhe_REGEXP = \
            r'''
        
            (?P<command>sendhealthcard=|sendhealthcard|sendhc=|sendhc|shc=|shc)         #omhe command 
            (?P<value>[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@  #email address
            (?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)
            \#*                                                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'shc')
        except:
            pass
            #print "no sendhc"
            #self.omhe[message_index] = "extraction error"
    
    #parse out sendhealthcard with fax number
    def parse_shcfax(self, message, message_index):

        omhe_REGEXP = \
            r'''
        
            (?P<command>sendhealthcard=|sendhealthcard|sendhc=|sendhc|shc=|shc)         #omhe command
            (?P<value>\d{10,11})                                                        #value ~ phone number
            \#*                                                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''

        try:
           self.generate_dict(message, message_index, omhe_REGEXP, 'shc')
        except:
            pass
            #print "no sendhc"
            #self.omhe[message_index] = "extraction error"
    
    #parse out healthcard with url    
    def parse_hcurl(self, message, message_index):
        omhe_REGEXP = \
            r'''
        
            (?P<command>healthcard=|healthcard|hc=|hc)      #omhe command
            (?P<value>http[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)   #value
            \#*                                             #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag

            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'hc')
        except:
            pass
            #print "no hc"
            #self.omhe[message_index] = "extraction error"
    
    #parse out gethealthcard
    def parse_ghc(self, message, message_index):
        omhe_REGEXP = \
            r'''
        
            (?P<command>gethealthcard|gethc|ghc)        #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)   #value
            \#*                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag

            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'ghc')
        except:
            pass
            #print "no gethc"
            #self.omhe[message_index] = "extraction error"
    
    ####################################################################
    #menstrual cycle
    ####################################################################
    #parse out getmenstrualcycle
    def parse_gmc(self, message, message_index):
        omhe_REGEXP = \
            r'''
            (?P<command>getmooncycle|getmcycle|getmc|gmc)   #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)       #value
            \#*                                             #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag

            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'gmc')
        except:
            pass
            #print "no gethc"
            #self.omhe[message_index] = "extraction error"
            
            
    #parse out sendmenstrualcycle with email
    def parse_smcemail(self, message, message_index):
        omhe_REGEXP = \
            r'''
            (?P<command>sendmooncycle=|sendmooncycle|sendmcycle=|sendmcycle|sendmc=|sendmc|smc=|smc)    #omhe command
                                                                                                        #email address
            (?P<value>[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@
            (?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)
            \#*                                                                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag                                                  #tag
            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'smc')
        except:
            pass

                
    #parse out menstrualcycle
    def parse_mc(self, message, message_index):
        omhe_REGEXP = \
            r'''

            (?P<command>cyclebeads=|cyclebeads|mooncycle=|mooncycle|mcycle=|mcycle|mc=|mc)  #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)                                       #value
            \#*                                                                             #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag

            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'mc')
        except:
            pass
        
    #parse out weight
    def parse_wt(self, message, message_index):
        omhe_REGEXP = \
            r'''

            (?P<command>weight=|weight|wt=|wt)              #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)       #value
            \#*                                             #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''

        try:
           self.generate_dict(message, message_index, omhe_REGEXP, 'wt')
        except:
            pass
        
    #parse out blood pressure
    def parse_bp(self, message, message_index):
        omhe_REGEXP = \
            r'''

            (?P<command>bloodpressure=|bloodpressure|bp=|bp)    #omhe command
            (?P<value>\d{1,3}/\d{1,3}p\d{1,3}                   #value defined as 102/80p70
            |                                                   #or
            \d{1,3}d\d{1,3}p\d{1,3}                             #value defined as 102d80p70
            |                                                   #or
            \d{1,3}d\d{1,3}                                    #value defined as 102d80
            |                                                   #or
            \d{1,3}/\d{1,3}                                    #value defined as 102/80
            |                                                   #or
            \d{3,3}\d{3,3}\d{3,3}                               #value defined as 102180100
            |                                                   #or
            \d{3,3}\d{3,3})                                     #value defined as 102180
            \#*                                                 #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''

        try:
           self.generate_dict(message, message_index, omhe_REGEXP, 'bp')
        except:
            pass
        
    #parse out gethealthcard
    def parse_gbp(self, message, message_index):
        omhe_REGEXP = \
            r'''
        
            (?P<command>getbloodpressure|getbp|gbp)        #omhe command
            (?P<value>[a-z0-9!$%&'*"+:./=?^_`{|}~-]*)   #value
            \#*                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag

            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'gbp')
        except:
            pass
            #print "no gethc"
            #self.omhe[message_index] = "extraction error"
            
            
    #parse out sendmenstrualcycle with email
    def parse_sbpemail(self, message, message_index):
        omhe_REGEXP = \
            r'''
            (?P<command>sendbloodpressure=|sendbloodpressure|sendbp=|sendbp|sbp=|sbp)    #omhe command
                                                                                                        #email address
            (?P<value>[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@
            (?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)
            \#*                                                                                         #tag indicator 
            (?P<tag>[a-z0-9!$%&'*"#+:./=?^_`{|}~-]*)     #tag
            '''

        try:
            self.generate_dict(message, message_index, omhe_REGEXP, 'sbp')
        except:
            pass

    
   
        
if __name__ == "__main__":
            
    try: 
        omhe_str=sys.argv[1]
    except(IndexError):
        omhe_str ="""bp120/80p60#dt20100101:122005Z#tzo-5 bp130/90p60#dt20100101:132005Z#tzo-8"""
    
    print "Input omhe string is: %s" % (omhe_str) 
    
    try:
        o = omheparser(omhe_str = omhe_str)
        omhelist = o.list
        print omhelist
    except:
        print "There was an error parsing the omhe string."

    
    
    
            
                
                
            
            
        
